<?php

/*
 *	微信接口模块 Class
 *	author	yanxf <walkfine@gmail.com>
 *	version	0.1
 */

class WechatAPI{
/*
    const TOKEN = '55541fec66fa44ce0a251f9e9702bc9c';
    const WEIXIN_NAME = 'gh_e645b3de5743';
	const APPID = 'wxa99ad5e76c3b16fd';
	const APPSECRET = 'a0a145c16e60301d87770d11f4a86f04';
	*/
/*
    const TOKEN = Config::model()->get('weixin_token');
    const WEIXIN_NAME = Config::model()->get('weixin_name');
	const APPID = Config::model()->get('weixin_appid');
	const APPSECRET = Config::model()->get('weixin_secret');
*/
	public $errcode;
	public $error;

    public $TOKEN;
    public $WEIXIN_NAME;
	public $APPID;
	public $APPSECRET;




	/*获取access_token */
	private function getAccessToken()
	{
		$access_token = Config::model()->get('access_token');
		$token_expires = Config::model()->get('token_expires');
		if($access_token != null &&  $token_expires > time())
		{
			//有请求后，自动续期
			//Config::model()->set('token_expires',time()+7200);
	//		return $access_token;
		}
		
		$url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='.$this->APPID.'&secret='.$this->APPSECRET;
		$json_data = $this->post($url);
		$data = CJSON::decode($json_data);
		if(empty($data['errcode']))
		{
			Config::model()->set('access_token',$data['access_token']);
			Config::model()->set('token_expires',time()+$data['expires_in']);
			return $data['access_token'];
		}else{
			//echo $json_data;
			$this->errcode = $data['errcode'];
			return false;
		}
	}





	/* 设置导航 */
	public function setNav($navs)
	{
		//$navs = CJSON::encode(CJSON::decode($navs));
		$url = 'https://api.weixin.qq.com/cgi-bin/menu/create?access_token='.$this->getAccessToken();
		$json_data = $this->post($url,$navs);
		$data = CJSON::decode($json_data);
		if(empty($data['errcode']))
		{
			return true;
		}else{
			//echo $json_data;
			$this->errcode = $data['errcode'];
			return false;
		}

	}








/* 发送客服消息
{
    "touser":"OPENID",
    "msgtype":"text",
    "text":
    {
         "content":"Hello World"
    }
}

{
    "touser":"OPENID",
    "msgtype":"image",
    "image":
    {
      "media_id":"MEDIA_ID"
    }
}

{
    "touser":"OPENID",
    "msgtype":"voice",
    "voice":
    {
      "media_id":"MEDIA_ID"
    }
}

{
    "touser":"OPENID",
    "msgtype":"video",
    "video":
    {
      "media_id":"MEDIA_ID",
      "title":"TITLE",
      "description":"DESCRIPTION"
    }
}

{
    "touser":"OPENID",
    "msgtype":"music",
    "music":
    {
      "title":"MUSIC_TITLE",
      "description":"MUSIC_DESCRIPTION",
      "musicurl":"MUSIC_URL",
      "hqmusicurl":"HQ_MUSIC_URL",
      "thumb_media_id":"THUMB_MEDIA_ID" 
    }
}

{
    "touser":"OPENID",
    "msgtype":"news",
    "news":{
        "articles": [
         {
             "title":"Happy Day",
             "description":"Is Really A Happy Day",
             "url":"URL",
             "picurl":"PIC_URL"
         },
         {
             "title":"Happy Day",
             "description":"Is Really A Happy Day",
             "url":"URL",
             "picurl":"PIC_URL"
         }
         ]
    }
}

type 类型 对应的 content 结构

text
content: string  'dfdfsdfds'

image
content: string  file_md5

voice
content: string file_md5

video
content: array ['media','title','description']

music
content: array [title , description , url , h_url , media]

news
content: array [[title,description,picurl,url] , [title,description,picurl,url] ]

*/
	public function send($touser,$content,$type='text')
	{
		$user = User::model()->detail($touser);
		$params['touser'] = $user->openid;
		$params['msgtype'] = $type;
		switch($type)
		{
			case 'text':
				$params['text'] = array('content'=>$content);
				break;
			case 'image':
				$params['image'] = array('media_id'=>$content);
				break;
			case 'voice':
				$params['voice'] = array('media_id'=>$content);
				break;
			case 'video':
				$params['video'] = array(
										'media_id'=>$content['media'],
										'title'=>$content['title'],
										'description'=>$content['description']
									);
				break;
			case 'music':
				$params['music'] = array(
      								"title"=>$content['title'],
									"description"=>$content['description'],
									"musicurl"=>$content['url'],
									"hqmusicurl"=>$content['h_url'],
									"thumb_media_id"=>$content['media']
    							);
				break;
			case 'news':
				$params['news'] = array('articles'=>$content);
				break;
		}
		$url = 'https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token='.$this->getAccessToken();
		$json_data = $this->post($url,$this->json_encode_cn($params));
		$data = CJSON::decode($json_data);
		if(empty($data['errcode']))
		{
			return true;
		}else{
			//echo $json_data;
			$this->errcode = $data['errcode'];
			return false;
		}
	}







/* 接收消息报文
	必有结构
	[msg_id,to_user,from_user,ctime,type]

type类型对应的扩展结构

text
	content


image
	media
	picurl

voice
	media
	format
	recognition

video
	media
	thumb

location
	x
	y
	scale
	label

link
	title
	description
	url



*/



	public function receive($content)
	{
		//echo '<textarea>'.$content.'</textarea>';

		$this->logPackets($content);

		$xml = new DOMDocument();
		$xml->loadXML($content);

		$data['to_user'] = $xml->getElementsByTagName("ToUserName")->item(0)->nodeValue;
		$data['from_user'] = $xml->getElementsByTagName("FromUserName")->item(0)->nodeValue;
		//记录活跃时间
		User::model()->active($data['from_user']);

		$data['ctime'] = $xml->getElementsByTagName("CreateTime")->item(0)->nodeValue;
		$data['type'] = $xml->getElementsByTagName("MsgType")->item(0)->nodeValue;


		switch($data['type'])
		{
			case 'text':
				$data['content'] = $xml->getElementsByTagName("Content")->item(0)->nodeValue;
				preg_match('/^@(?P<touser>\d+)$/',$data['content'],$matches);
				if(!empty($matches['touser']))
				{
					return $this->connect($data['from_user'],$matches['touser']);
				}
				if($data['content'] == 'q' || $data['content'] == 'exit')
				{
					return $this->quit($data['from_user']);
				}
				break;

			case 'image':
				$data['media'] = $xml->getElementsByTagName("MediaId")->item(0)->nodeValue;
				$data['picurl'] = $xml->getElementsByTagName("PicUrl")->item(0)->nodeValue;
				$this->addMedia($data['media'],'image','jpg');
				break;

			case 'voice':
				$data['media'] = $xml->getElementsByTagName("MediaId")->item(0)->nodeValue;
				$data['format'] = $xml->getElementsByTagName("Format")->item(0)->nodeValue;
				//开启语音识别
				$data['recognition'] = $xml->getElementsByTagName("Recognition")->item(0)->nodeValue;
				
				$this->addMedia($data['media'],'voice',$data['format']);
				break;

			case 'video':
				$data['media'] = $xml->getElementsByTagName("MediaId")->item(0)->nodeValue;
				$data['thumb'] = $xml->getElementsByTagName("ThumbMediaId")->item(0)->nodeValue;
				$this->addMedia($data['media'],'video','mp4');
				$this->addMedia($data['thumb'],'thumb','jpg');
				break;

			case 'location':
				$data['x'] = $xml->getElementsByTagName("Location_X")->item(0)->nodeValue;
				$data['y'] = $xml->getElementsByTagName("Location_Y")->item(0)->nodeValue;
				$data['scale'] = $xml->getElementsByTagName("Scale")->item(0)->nodeValue;
				$data['label'] = $xml->getElementsByTagName("Label")->item(0)->nodeValue;
				break;

			case 'link':
				$data['title'] = $xml->getElementsByTagName("Title")->item(0)->nodeValue;
				$data['description'] = $xml->getElementsByTagName("Description")->item(0)->nodeValue;
				$data['url'] = $xml->getElementsByTagName("Url")->item(0)->nodeValue;
				break;

			case 'event':
				$event = $xml->getElementsByTagName("Event")->item(0)->nodeValue;
				switch(strtolower($event))
				{
					case 'subscribe':
						$event_key = $xml->getElementsByTagName("EventKey")->item(0)->nodeValue;
						$result = $this->subscribe($data['from_user']);

						if(!empty($event_key))
						{
							$ticket = $xml->getElementsByTagName("Ticket")->item(0)->nodeValue;
							return $this->scan($data['from_user'],str_replace('qrscene_','',$event_key));
						}else
							return $result;
						break;

					case 'unsubscribe':
						return $this->subscribe($data['from_user'],false);

					case 'scan'://原来SCAN
						$event_key = $xml->getElementsByTagName("EventKey")->item(0)->nodeValue;
						$ticket = $xml->getElementsByTagName("Ticket")->item(0)->nodeValue;
						
						return $this->scan($data['from_user'],str_replace('qrscene_','',$event_key));
						break;

					case 'location'://原来LOCATION
						$latitude = $xml->getElementsByTagName("Latitude")->item(0)->nodeValue;
						$longitude = $xml->getElementsByTagName("Longitude")->item(0)->nodeValue;
						$precision = $xml->getElementsByTagName("Precision")->item(0)->nodeValue;
						//更新地理位置
						return User::model()->location($data['from_user'],$latitude,$longitude,$precision);
						
						break;

					case 'click'://原来CLICK
						$event_key = $xml->getElementsByTagName("EventKey")->item(0)->nodeValue;
						$reply = $this->handler($data['from_user'],$event_key);
						return $reply; 
				}
				break;
		}
		$data['msg_id'] = $xml->getElementsByTagName("MsgId")->item(0)->nodeValue;
		return $this->saveMsg($data);
		//$result = $this->saveMessage($data);

	}

	public function scan($openid,$qrscene)
	{
		$result = QR::model()->event($qrscene, $openid);
		//$content = '好的，好的！我知道你扫描了:'.$qrscene;
		return $this->reply($openid,$result['content'],$result['type']);
	}

	public function subscribe($openid,$type=true)
	{
		$bhv = new UserBehavior;
		if($type)
		{
			$bhv->add($openid);
			$content = Config::model()->get('weixin_hello');
			if(!empty($content))
				return $this->reply($openid,$content);
			else
				return true;
		}else{
			return $bhv->unSubscribe($openid);
		}
	}



/* 被动响应回复 
type 类型 对应的 content 结构

text
content: string  'dfdfsdfds'

image
content: string  file_md5

voice
content: string file_md5

video
content: array ['media','title','description']

music
content: array [title , description , url , h_url , media]

news
content: array [[title,description,picurl,url] , [title,description,picurl,url] ]



*/
	public function reply($touser,$content,$type='text')
	{
		$xml = new XML;
		
		$data['ToUserName'] = $touser;
		$data['FromUserName'] = $this->WEIXIN_NAME;
		$data['CreateTime'] = time();
		$data['MsgType'] = $type;
		switch($type)
		{
			case 'text':
				$data['Content'] = $content;
				break;
			case 'image':
				$data['Image'] = array('MediaId'=>$content);
				break;
			case 'voice':
				$data['Voice'] = array('MediaId'=>$content);
				break;
			case 'video':
				$data['Video'] = array(
									'MediaId'=>$content['media'],
									'Title'=>$content['title'],
									'Description'=>$content['description']
								);
			case 'music':
				$data['Music'] = array(
									'Title'=>$content['title'],
									'Description'=>$content['description'],
									'MusicUrl'=>$content['url'],
									'HQMusicUrl'=>$content['h_url'],
									'ThumbMediaId'=>$content['media']
								);
				break;

			case 'news':
				$data['ArticleCount'] = count($content);
				$data['Articles'] = '<xml>';
				foreach($content as $value)
				{
					$item = array(
								'item'=>array(
									'Title'=>$value['title'],
									'Description'=>$value['description'],
									'PicUrl'=>$value['picurl'],
									'Url'=>$value['url']
									)
								);
					$data['Articles'] = $data['Articles'] . $xml->arrayToXML($item);
				}
					$data['Articles'] = $data['Articles'] . '</xml>';

				break;
				
				
		}
		$rp_xml = $xml->create($data);
		
		$this->logPackets($rp_xml,3);
		return $rp_xml;
	}











	public function getUserList()
	{
		//一次最多10000人，超过部分使用next_openid
		//https://api.weixin.qq.com/cgi-bin/user/get?access_token=ACCESS_TOKEN&next_openid=NEXT_OPENID
		$url = 'https://api.weixin.qq.com/cgi-bin/user/get?access_token='.$this->getAccessToken();
		$json_data = $this->post($url);
		$data = CJSON::decode($json_data);
		if(!empty($data['errcode']))
		{
			//echo $json_data;
			$this->errcode = $data['errcode'];
			return false;
		}
		$users = $data['data']['openid'];

		while($data['count'] < $data['total'] && !empty($data['next_openid']))
		{
			$url = 'https://api.weixin.qq.com/cgi-bin/user/get?access_token='.($this->getAccessToken()).'&next_openid='.$data['next_openid'];
			$json_data = $this->post($url);
			$data = CJSON::decode($json_data);
			$users = array_merge($users,$data['data']['openid']);
		}
		return $users;
	}

	public function getUserDetail($open_id)
	{
		$url = 'https://api.weixin.qq.com/cgi-bin/user/info?access_token='.$this->getAccessToken().'&openid='.$open_id;
		$json_data = $this->post($url);
		$data = CJSON::decode($json_data);
		if(!empty($data['errcode']))
		{
			//echo $json_data;
			$this->errcode = $data['errcode'];
			return false;
		}
		if($data['subscribe']==0)
			return false;
		return $data;
	}


	public function getQRCodeByApi($scene_id,$type=1)
	{
		$url = 'https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token='.$this->getAccessToken();
		$params['expire_seconds'] = 1800;
		if($type)
			$params['action_name'] = 'QR_LIMIT_SCENE';
		else
			$params['action_name'] = 'QR_SCENE';
		$params['action_info'] = array('scene'=>array('scene_id'=>$scene_id));
		
		$json_data = $this->post($url,json_encode($params));

		$data = CJSON::decode($json_data);
		if(!empty($data['errcode']))
		{
			$this->errcode = $data['errcode'];
			return false;
		}
		$url = 'https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket='.urlencode($data['ticket']);

		//$qrcode = $this->post($url);
		$qrcode = $this->post($url);
		return $qrcode;
	}






	public function getQRCode($scene_id,$type=1)
	{
		$qrcode = $this->getQRCodeByApi($scene_id,$type);
		$bhv = new FilesComponent;
		$img = $bhv->set($qrcode,'qrcode.jpg','image/jpeg');
		if(!$img){
			$result['error'] = $bhv->error;
		}else{
			$result = $img;
		}
		return $result;
	}







	private function handler($touser,$event)
	{
		$type = 'news';
		switch($event)
		{
			case 'GET_TRAFFIC':
				$data = $this->getTraffic();
				break;
			case 'GET_FOOD':
				$data = Raider::model()->getFoodList();
				break;
			case 'GET_LIVE':
				$data = $this->getLive();
				break;
			case 'GET_HOTEL':
				$data = Raider::model()->getHotelList();
				break;
			case 'SHARE':
				$type = 'text';
				$data = $this->share($touser);
				break;
			case 'GET_COMMENT':
				$data = $this->getComment();
				break;
			case 'GET_ACTIVE':
				$data = Activity::model()->getActiveList();
				break;
			case 'GET_COUPON':
				$data = Promotion::model()->getCouponList();
				break;
			case 'GET_MERCHANTS':
				$data = Article::model()->getMerchantsList();
				break;
			case 'GET_CHARITY':
				$data = Article::model()->getCharityList();
				break;
			case 'GET_NEWS':
				$data = Article::model()->getNewsList();
				break;
			case 'SUGGEST':
				$type = 'text';
				$data = $this->suggest($touser);
				break;
		}
		if(empty($data))
			return $this->reply($touser,'抱歉～暂时没有相关信息呢！','text');
		return $this->reply($touser,$data,$type);
	}






	public function connect($user,$touser)
	{
		Config::model()->set($user,'talk');
		$talk_to = Config::model()->set($user.'_talk',$touser);
		Config::model()->set($user.'_time',time()+600);
		$user_detail = User::model()->detail($touser);

		$message = '建立对话成功，您后面发送所有消息将转发给'.$user_detail['nickname'].'，退出对话请回复 q 或 exit 。';
		return $this->reply($user,$message);
	}



	public function quit($user)
	{
		Config::model()->set($user,'');
		Config::model()->set($user.'_talk','');
		return $this->reply($user,'退出成功');
	}



	public function share($user)
	{
		$type = Config::model()->get($user);
		if($type == 'share')
		{
			$message = '您已经取消分享，感谢使用!';
			Config::model()->set($user,'');
			return $message;
		}
		Config::model()->set($user,'share');
		$message = "您开启分享模式，您后面发送的一条消息将被作为分享保存。\r\n查看其他人分享，请 <a href='http://".$_SERVER['HTTP_HOST']."/share'>点击这里</a>。\r\n取消分享请再次点击分享导航。";
		return $message;
	}

	private function suggest($user)
	{
		$type = Config::model()->get($user);
		if($type == 'suggest')
		{
			$message = '您已经取消投诉，感谢使用!';
			Config::model()->set($user,'');
			return $message;
		}
		
		Config::model()->set($user,'suggest');
		$message = '您处于投诉模式，您后面发送的一条消息将被作为投诉信息保存。取消投诉请再次点击投诉导航。';
		return $message;
	}




	private function saveMsg($data)
	{
		$openid = $data['from_user'];
		$type = Config::model()->get($data['from_user']);
		
		$user = User::model()->detailByOpenId($data['from_user']);
		$data['from_user'] = $user->id;
		if(!empty($type))
		{
			switch($type)
			{
				case 'share'://分享
					Message::model()->saveShare($data);
					$message = "感谢您的分享。\r\n查看其他人分享，请<a href='http://".$_SERVER['HTTP_HOST']."/share'>点击这里</a>";
					Config::model()->set($openid,'');
					return $this->reply($openid,$message);

				case 'suggest'://投诉
					Message::model()->saveComplaints($data);
					$message = '感谢您的投诉，我们会尽快处理。';
					Config::model()->set($openid,'');
					return $this->reply($openid,$message);
				case 'talk'://众乐乐
					$time = Config::model()->get($openid.'_time');
					if($time > time())
					{
						Config::model()->set($openid.'_time',time()+600);
						$data['to_user'] = Config::model()->get($openid.'_talk');
						return Message::model()->sendNearby($data);
					}else{
						$this->quit($ipenid);
					}
			}
		}
		Message::model()->saveToHuili($data);
		return 'success';
	}
















	private function getTraffic()
	{

		$item['title'] = '周边交通';
		$item['description'] = '';
		$item['picurl'] = 'http://'.$_SERVER['HTTP_HOST'].'/statics/images/traffic/banner.png';
		$item['url'] = 'http://'.$_SERVER['HTTP_HOST'].'/traffic/gps';
		$data[] = $item;
		
		$item['title'] = '自驾信息';
		$item['description'] = '';
		$item['picurl'] = 'http://'.$_SERVER['HTTP_HOST'].'/statics/images/traffic/car2.png';
		$item['url'] = 'http://'.$_SERVER['HTTP_HOST'].'/traffic/drive';
		$data[] = $item;
		
		$item['title'] = '公交信息';
		$item['description'] = '';
		$item['picurl'] = 'http://'.$_SERVER['HTTP_HOST'].'/statics/images/traffic/bus2.png';
		$item['url'] = 'http://'.$_SERVER['HTTP_HOST'].'/traffic/bus';
		$data[] = $item;
		
		$item['title'] = '导航路径';
		$item['description'] = '';
		$item['picurl'] = 'http://'.$_SERVER['HTTP_HOST'].'/statics/images/traffic/gps2.png';
		$item['url'] = 'http://'.$_SERVER['HTTP_HOST'].'/traffic/gps';
		$data[] = $item;
/*
		$item['title'] = '惠里导游图';
		$item['description'] = '';
		$item['picurl'] = 'http://weixin.vlli.net/statics/images/traffic/daoyou.png';
		$item['url'] = 'http://weixin.vlli.net/traffic/tourist_map';
		$data[] = $item;
*/
		return $data;
	}

	private function getLive()
	{
		$data = Shopping::model()->getShoppingList();
		return $data;


		$item['title'] = '游乐生活';
		$item['description'] = '';
		$item['picurl'] = 'http://'.$_SERVER['HTTP_HOST'].'/statics/images/live/banner.png';
		$item['url'] = 'http://'.$_SERVER['HTTP_HOST'].'/raider/riding';
		$data[] = $item;
		
		$item['title'] = '惠里骑游';
		$item['description'] = '';
		$item['picurl'] = 'http://'.$_SERVER['HTTP_HOST'].'/statics/images/live/bike2.png';
		$item['url'] = 'http://'.$_SERVER['HTTP_HOST'].'/raider/riding';
		$data[] = $item;
		
		$item['title'] = '惠里摄影';
		$item['description'] = '';
		$item['picurl'] = 'http://'.$_SERVER['HTTP_HOST'].'/statics/images/live/photo2.png';
		$item['url'] = 'http://'.$_SERVER['HTTP_HOST'].'/raider/photograph';
		$data[] = $item;
		
		$item['title'] = '惠里养生';
		$item['description'] = '';
		$item['picurl'] = 'http://'.$_SERVER['HTTP_HOST'].'/statics/images/live/coffee2.png';
		$item['url'] = 'http://'.$_SERVER['HTTP_HOST'].'/raider/health';
		$data[] = $item;
		
		$item['title'] = '惠购物';
		$item['description'] = '';
		$item['picurl'] = 'http://'.$_SERVER['HTTP_HOST'].'/statics/images/live/cart.png';
		$item['url'] = 'http://'.$_SERVER['HTTP_HOST'].'/shopping/list';
		$data[] = $item;

		return $data;
	}




	private function getComment()
	{
		$item['title'] = '游客点评';
		$item['description'] = '';
		$item['picurl'] = 'http://'.$_SERVER['HTTP_HOST'].'/statics/images/comment.jpg';
		$item['url'] = 'http://'.$_SERVER['HTTP_HOST'].'/';
		$data[] = $item;

		$comments = ShopComment::model()->getWXCommentList();
		$data = array_merge($data,$comments);
		return $data;
	}






	public function addMedia($media_id,$type,$ext)
	{
		$criteria = new CDbCriteria;
		$criteria->addCondition('rt = 0 AND media_id = "'.$media_id.'"');
		$model = Media::model()->find($criteria);
		if(empty($model))
		{
			$model = new Media;
		}
		$model->media_id = $media_id;
		$model->type = $type;
		$model->ext = $ext;
		$model->ctime = time();
		$model->rt = 0;
		return $model->save();
	}

	public function mediaToFile($media_id)
	{
		$criteria = new CDbCriteria;
		$criteria->addCondition('rt = 0 AND media_id = "'.$media_id.'"');
		$model = Media::model()->find($criteria);
		if(empty($model))
		{
			echo '没有对应的media';
			return false;
		}
		if(empty($model->hash))
		{
			$model = $this->download($media_id);
		}
		return $model->hash;
	}

	public function fileToMedia($hash,$type)
	{
		$criteria = new CDbCriteria;
		$criteria->addCondition('rt = 1 AND hash = "'.$hash.'"');
		$model = Media::model()->find($criteria);
		if(empty($model) || empty($model->media_id))
		{
			$model = $this->upload($hash,$type);
		}
		if(!empty($model)){
			if( (time()- ($model->ctime))>(3600*24*3) )
				$model = $this->upload($hash,$type);
		}else
			return false;
		
		return $model->media_id;
	}





	public function upload($hash,$type='image')
	{
		if($type == 'music')
			$up_type = 'thumb';
		else
			$up_type = $type;
		$url = 'http://file.api.weixin.qq.com/cgi-bin/media/upload?access_token='.$this->getAccessToken().'&type='.$up_type;

		$file = new FilesComponent;
		$path = $file->getPath($hash);
		
		$file_info = $file->getFileInfo($hash); 
		$ext = $file_info['file_extension'];
		switch($type)
		{
			case 'image':
				$allow_ext = array('jpg','jpeg');
				break;
			case 'voice':
				$allow_ext = array('amr','mp3');
				break;
			case 'video':
				$allow_ext = array('mp4');
				break;
			case 'music':
				$allow_ext = array('jpg','jpeg');
				break;
			default:
				echo 'type格式不存在';
				return false;
		}
		if(!in_array($ext,$allow_ext))
		{
			echo '不允许上传的格式';
			return false;
		}
		
		if (version_compare(phpversion(), '5.5.0', '<')) {
    		// php version isn't high enough
			$tmp_path = '/tmp/'.$hash.'.'.$ext;
			if (!copy($path, $tmp_path)) {
				echo "failed to copy $path...\n";
				return false;
			}
			$data['media'] = "@".$tmp_path;
		}else{
		//你妹啊php 5.5不支持@filename的方法，需要使用CurlFile，最坑爹的是CurlFile 要求php >= 5.5
		//$cfile = curl_file_create('cats.jpg','image/jpeg','test_name');
		//$args['file'] = new CurlFile('filename.png', 'image/png', 'filename.png');

		//没有后缀，提示不合法的文件类型，艹～
			$data['media'] = new CurlFile($path, $file_info['file_type'], $hash.'.'.$ext);
		}

		$media = $this->post($url,$data);
		$media = json_decode($media,true);
		if(!empty($media['errcode']))
		{
			echo $this->error[$media['errcode']];
			return false;
		}

		//保存到附件表
		//{"type":"TYPE","media_id":"MEDIA_ID","created_at":123456789}
		$criteria = new CDbCriteria;
		$criteria->addCondition('rt = 1 AND hash = "'.$hash.'"');
		$model = Media::model()->find($criteria);
		if(empty($model))
		{
			$model = new Media;
			$model->hash = $hash;
		}
		$model->type = $media['type'];
		$model->ext = $ext;
		$model->ctime = $media['created_at'];
		$model->media_id = $media['media_id'];
		$model->rt = 1;
		$model->save();
		return $model;
	}

	public function download($media_id)
	{
		$url = 'http://file.api.weixin.qq.com/cgi-bin/media/get?access_token='.$this->getAccessToken().'&media_id='.$media_id;
		$file = Curl::post($url);

		//保存文件
		$criteria = new CDbCriteria;
		$criteria->addCondition('rt = 0 AND media_id = "'.$media_id.'"');
		$model = Media::model()->find($criteria);
		if(empty($model))
		{
			return false;
		/*
			$model = new Media;
			switch($file['info']['content_type'])
			{
				case 'image/jpeg':
					$type = 'image';
					break;
				default:
					$type = 
			}
			$model->type = '';
		*/
		}

		$bhv = new FilesComponent;
		$result = $bhv->set($file['content'],$media_id.'.'.$model->ext,$file['info']['content_type']);
		if(empty($result))
			return false;

		$model->hash = $result['hash'] ;
		$model->save();
		return $model;

	}

















	public function oauth2($referer_openid='')
	{ 
		if (YII_DEBUG) {
			Yii::app()->user->setState('user_id',10);
			return true;
		}

		if(strpos($_SERVER['REQUEST_URI'],'files') !== false)
			return true;
		if(strpos($_SERVER['REQUEST_URI'],'statics') !== false)
			return true;
		if(strpos($_SERVER['REQUEST_URI'],'admin') !== false)
			return true;
		if(strpos($_SERVER['REQUEST_URI'],'interface') !== false)
			return true;
		if(strpos($_SERVER['REQUEST_URI'],'images') !== false)
			return true;
		if(strpos($_SERVER['REQUEST_URI'],'download') !== false)
			return true;

		$user_id = Yii::app()->user->getState('user_id');
		if(empty($user_id))
		{
			if(empty($_GET['code']))
			{
				$reurl =  'http://'.$_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
				$url = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid='.$this->APPID.'&redirect_uri='.urlencode($reurl).'&response_type=code&scope=snsapi_base&state='.$referer_openid.'#wechat_redirect';
				Yii::app()->request->redirect($url);
			}else{
				if(empty($_GET['code']))
					echo '无法获取用户身份，可能无法提供信息';
				else{
					$url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid='.$this->APPID.'&secret='.$this->APPSECRET.'&code='.$_GET['code'].'&grant_type=authorization_code';
					$result = $this->post($url);
					$result = json_decode($result,true); 
					if(!empty($result['errcode']))
					{
						echo $this->error[$result['errcode']];
						return false;
					}
					$user = User::model()->detailByOpenId($result['openid']);
					Yii::app()->user->setState('user_id',$user['id']);
				}
				return true;
			}
		}
	}









	public function sendAll($content,$type='text')
	{
		$users = User::model()->getActiveUser();
		if(empty($users))
			return false;
		$i = 0;
		foreach($users as $user)
		{
			$this->send($user['id'],$content,$type);
			$i++;
		}
		return $i;
	}





	public function initUser()
	{
		$users = $this->getUserList();
		if(!empty($this->errcode))
		{
			echo $this->error[$this->errcode];
			return false;
		}
		$bhv = new UserBehavior;
		$i = 0;
		foreach($users as $open_id)
		{
			if($bhv->add($open_id))
				$i++;
		}
		return $i;
	}

	public function updateUser()
	{
		$users = $this->getUserList();
		if(!empty($this->errcode))
		{
			echo $this->error[$this->errcode];
			return false;
		}
		$bhv = new UserBehavior;
		$i = 0;
		foreach($users as $open_id)
		{
			if($bhv->updateUser($open_id))
				$i++;
		}
		return $i;
	}



	public function initFile()
	{
		
	
	}
	//2017-3-2 新增方法 wangw
	public static function getRandChar($length = 16){
        $str = null;
        $strPol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
        $max = strlen($strPol)-1;

        for($i=0;$i<$length;$i++){
            $str.=$strPol[rand(0,$max)];//rand($min,$max)生成介于min和max两个数之间的一个随机整数
        }

        return $str;
     }
	public static function AccessToken(){
		$api = new WeiXinAPI;
        $str =  $api->getAccessToken();
        return $str;
     }




















    public function checkSignature()
    {
        // return true;
        $signature = Yii::app()->request->getQuery('signature');
        $timestamp = Yii::app()->request->getQuery('timestamp');
        $nonce = Yii::app()->request->getQuery('nonce');
        if (empty($signature) || empty($timestamp) || empty($nonce)) {
            return false;
        }

        $token = $this->TOKEN;
        $tmpArr = array($token, $timestamp, $nonce);
        sort($tmpArr);
        $tmpStr = implode($tmpArr);
        $tmpStr = sha1($tmpStr);

        if ($tmpStr == $signature) {
            return true;
        } else {
            return false;
        }
    }




	protected static function mkheader()
	{
		$headers = array(
			'Host: erp.wanthings.com',
			'Connection: keep-alive',
			'Cache-Control: no-cache',
			'Pragma: no-cache',
			'User-Agent: Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537.4',
			'Accept: image/png,image/*;q=0.8,*/*;q=0.5',
			'Referer: http://www.scjj.gov.cn:8635/',
			'Accept-Encoding: gzip,deflate,sdch',
			'Accept-Language: en-US,en;q=0.8,zh-CN;q=0.6,zh;q=0.4',
			'Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3',
//			'Cookie: ASP.NET_SessionId=usvzvwrp2qkwo3ejd5miwq45'
		);
		return $headers;
	}






	/* 使json_encode不转义中文字符为unicode */
	private function json_encode_cn($array)
	{
		return urldecode(json_encode($this->array_cn($array)));
		//php 5.4 支持 JSON_UNESCAPED_UNICODE
		//return json_encode($array, JSON_UNESCAPED_UNICODE)
	}

	private function array_cn($array)
	{
		$data = array();
		foreach($array as $key=>$value)
		{
			if(is_array($value))
			{
				$data[$key] = $this->array_cn($value);
			}else{
				$data[$key] = urlencode($value);
			}
		}
		return $data;
	
	}







	public function __construct()
	{

		//parent::__construct();
   	 	//$this->TOKEN = Config::model()->get('weixin_token');
   		//$this->WEIXIN_NAME = Config::model()->get('weixin_name');
		//$this->APPID = Config::model()->get('weixin_appid');
		//$this->APPSECRET = Config::model()->get('weixin_secret');
		$this->TOKEN = '55541fec66fa44ce0a251f9e9702bc9c';
   		$this->WEIXIN_NAME = '西西汇';
		$this->APPID = 'wx304eca37b16cdb5d';
		$this->APPSECRET = '78ea814983c53984324680cc0e6c481a';

		$error['-1']	= '系统繁忙';
		$error['0']	= '请求成功';
		$error['40001']	= '获取access_token时AppSecret错误，或者access_token无效';
		$error['40002']	= '不合法的凭证类型';
		$error['40003']	= '不合法的OpenID';
		$error['40004']	= '不合法的媒体文件类型';
		$error['40005']	= '不合法的文件类型';
		$error['40006']	= '不合法的文件大小';
		$error['40007']	= '不合法的媒体文件id';
		$error['40008']	= '不合法的消息类型';
		$error['40009']	= '不合法的图片文件大小';
		$error['40010']	= '不合法的语音文件大小';
		$error['40011']	= '不合法的视频文件大小';
		$error['40012']	= '不合法的缩略图文件大小';
		$error['40013']	= '不合法的APPID';
		$error['40014']	= '不合法的access_token';
		$error['40015']	= '不合法的菜单类型';
		$error['40016']	= '不合法的按钮个数';
		$error['40017']	= '不合法的按钮个数';
		$error['40018']	= '不合法的按钮名字长度';
		$error['40019']	= '不合法的按钮KEY长度';
		$error['40020']	= '不合法的按钮URL长度';
		$error['40021']	= '不合法的菜单版本号';
		$error['40022']	= '不合法的子菜单级数';
		$error['40023']	= '不合法的子菜单按钮个数';
		$error['40024']	= '不合法的子菜单按钮类型';
		$error['40025']	= '不合法的子菜单按钮名字长度';
		$error['40026']	= '不合法的子菜单按钮KEY长度';
		$error['40027']	= '不合法的子菜单按钮URL长度';
		$error['40028']	= '不合法的自定义菜单使用用户';
		$error['40029']	= '不合法的oauth_code';
		$error['40030']	= '不合法的refresh_token';
		$error['40031']	= '不合法的openid列表';
		$error['40032']	= '不合法的openid列表长度';
		$error['40033']	= '不合法的请求字符，不能包含\uxxxx格式的字符';
		$error['40035']	= '不合法的参数';
		$error['40038']	= '不合法的请求格式';
		$error['40039']	= '不合法的URL长度';
		$error['40050']	= '不合法的分组id';
		$error['40051']	= '分组名字不合法';
		$error['41001']	= '缺少access_token参数';
		$error['41002']	= '缺少appid参数';
		$error['41003']	= '缺少refresh_token参数';
		$error['41004']	= '缺少secret参数';
		$error['41005']	= '缺少多媒体文件数据';
		$error['41006']	= '缺少media_id参数';
		$error['41007']	= '缺少子菜单数据';
		$error['41008']	= '缺少oauth code';
		$error['41009']	= '缺少openid';
		$error['42001']	= 'access_token超时';
		$error['42002']	= 'refresh_token超时';
		$error['42003']	= 'oauth_code超时';
		$error['43001']	= '需要GET请求';
		$error['43002']	= '需要POST请求';
		$error['43003']	= '需要HTTPS请求';
		$error['43004']	= '需要接收者关注';
		$error['43005']	= '需要好友关系';
		$error['44001']	= '多媒体文件为空';
		$error['44002']	= 'POST的数据包为空';
		$error['44003']	= '图文消息内容为空';
		$error['44004']	= '文本消息内容为空';
		$error['45001']	= '多媒体文件大小超过限制';
		$error['45002']	= '消息内容超过限制';
		$error['45003']	= '标题字段超过限制';
		$error['45004']	= '描述字段超过限制';
		$error['45005']	= '链接字段超过限制';
		$error['45006']	= '图片链接字段超过限制';
		$error['45007']	= '语音播放时间超过限制';
		$error['45008']	= '图文消息超过限制';
		$error['45009']	= '接口调用超过限制';
		$error['45010']	= '创建菜单个数超过限制';
		$error['45015']	= '回复时间超过限制';
		$error['45016']	= '系统分组，不允许修改';
		$error['45017']	= '分组名字过长';
		$error['45018']	= '分组数量超过上限';
		$error['46001']	= '不存在媒体数据';
		$error['46002']	= '不存在的菜单版本';
		$error['46003']	= '不存在的菜单数据';
		$error['46004']	= '不存在的用户';
		$error['47001']	= '解析JSON/XML内容错误';
		$error['48001']	= 'api功能未授权';
		$error['50001']	= '用户未授权该api';
		
		$this->error = $error;
	}

	public function post($url,$data=null,$type=null)
	{
		if(!empty($data))
		{
			if(is_string($data))
				$this->logPackets($data,2,$url);
			else
				$this->logPackets('貌似是文件',2,$url);
		}
		$result = Curl::post($url,$data,$type);

		if(is_string($result['content']))
			$log_content = 'header:'.json_encode($result['info'])."\r\n".'content:'.$result['content'];
		else
			$log_content = 'header:'.json_encode($result['info'])."\r\n".'content:貌似是文件呀';
		
		$this->logPackets($log_content,4);

		if(!empty($result))
			return $result['content'];
		return false;
	}


	public function logPackets($content,$type=1,$url=null)
	{
		$model = new Packets;
		$model->content = $content;
		$model->ctime = time();
		$model->type = $type;
		if(!empty($url))
			$model->url = $url;
		$model->save();
	}
}
